#ifndef _FAVCAVCODEC_H_
	#define _FAVCAVCODEC_H_

	// ioctl flag, should be consistent with driver definition
	#define FAVC_IOCTL_DECODE_INIT    0x4170
	#define FAVC_IOCTL_DECODE_FRAME   0x4172
	
	#define FAVC_IOCTL_ENCODE_INIT    0x4173
	#define FAVC_IOCTL_ENCODE_FRAME   0x4175
	#define FAVC_IOCTL_GET_SYSINFO  0x4177
	

	/* API return values */
	#define FARADAY_OK  0 			// Operation succeed.
	#define FARADAY_ERR_MEMORY 1	// Operation failed (out of memory).
	#define FARADAY_ERR_API 2			// Operation failed (API version error).
	#define FARADAY_ERR_HEADER 3
	#define FARADAY_ERR_FILL_BUFFER 4
	#define FARADAY_ERR_FILE_OPEN 5
	#define FARADAY_HEADER_READY 6
	#define FARADAY_BS_EMPTY 7
	#define FARADAY_WAITING 8
	typedef uint32_t (* REQUEST_BS_PTR) (uint8_t * const pu8bs_buf,
							  uint32_t const u32byte_num);
	typedef void (* SEM_WAIT_PTR)(void * pSem);
	typedef void (* SEM_SIGNAL_PTR)(void * pSem);
	typedef void *(* FAVC_DMA_MALLOC_PTR)(uint32_t size, uint16_t align_size,	uint8_t reserved_size, void ** phy_ptr);
	typedef void (* FAVC_DMA_FREE_PTR)(void * virt_ptr, void * phy_ptr);
         typedef void *(* FAVC_MALLOC_PTR)(unsigned int size, unsigned char align_size, unsigned char reserved_size);
         typedef void (* FAVC_FREE_PTR)(void * virt_ptr);	

//H.264 Decoder ioctl Interface Data Structure 
	typedef struct
	{
//		uint32_t u32API_version;
		uint32_t *pu32BaseAddr;
		uint32_t u32MaxWidth;
		uint32_t u32MaxHeight;
		uint32_t u32FrameBufferWidth;
		uint32_t u32FrameBufferHeight;
		uint32_t u32CacheAlign;
		uint32_t u32Pkt_size;
		uint32_t pu8Pkt_buf;		
		uint32_t pu8Display_addr[3];
		uint32_t got_picture;
		uint32_t u32BS_buf_sz;
		//uint8_t * pu8FrameBaseAddr_phy;	// output frame buffer, must 8 bytes align.
		//uint8_t * pu8FrameBaseAddr_U_phy;	// frame buffer (U) if output format is yuv420, must 8 bytes align.
		//uint8_t * pu8FrameBaseAddr_V_phy;	// frame buffer (V) if output format is yuv420, must 8 bytes align.

		FAVC_DMA_MALLOC_PTR pfnDmaMalloc;	// "set to NULL", means the 4 above buffers will be prepared enternallly
		FAVC_DMA_FREE_PTR pfnDmaFree;			// Don't care when pfnDmaMalloc == NULL
		FAVC_MALLOC_PTR pfnMalloc;	// "set to NULL", means the 4 above buffers will be prepared enternallly
		FAVC_FREE_PTR pfnFree;			// Don't care when pfnDmaMalloc == NULL

		uint8_t * pu8BitStream_phy;			// physical address. buffer for bitstream
		uint8_t * pu8BitStream;				// virtual address.

		SEM_WAIT_PTR pfnSemWait;
		SEM_SIGNAL_PTR pfnSemSignal;
		void * pvSemaphore;
	} FAVC_DEC_PARAM;
	
//H.264 Encoder ioctl Interface Data Structure 

typedef struct {
  /// The base address of hardware core.
  unsigned int   u32BaseAddr; /**< User can use this variable to set the base
                               *   address of hardware core.
                               */                   
  // The encoded bitrate in bps.
  unsigned int   u32BitRate;
  
  /// The width of encoded frame in pels.
  unsigned int   u32FrameWidth; /**< User can use this variable to specify the <B>width</B> of 
                                 *   encoded frame in pels.
                                 */
  /// The height of encoded frame in pels.
  unsigned int   u32FrameHeight; /**< User can use this variable to specify the <B>height</B> of 
                                  *   encoded frame in pels.
                                  */
  /// The base frame rate.
  unsigned int   fFrameRate; /**< To set the encoded frame rate per second.
                              */		                                
  /// The frame interval between I-frames.
  unsigned int   u32IPInterval; /**< This variable was used to set the interval between I-frames.
                                 */
  /// The maximum quantization value.
  unsigned int   u32MaxQuant;
  /// The minimum quantization value.
  unsigned int   u32MinQuant;
  /// The frame quantization value.
  unsigned int   u32Quant; /**<
                            *   To specify the quantization value. 
                            */
                            
  /// The number of frames to be encoded
  unsigned int no_frames; /**< It specifies the number of frames to be encoded.
                           *   Note that this variable is only used for verification
                           *   purpose. You don't have to specify this option in real case.
                           */
  /// The transform coefficients threshold.
  unsigned int threshold_disable; /**< to disable transform coefficients threshold 
                                   */  
  /// The chroma coefficients threshold (0 ~ 7).
  unsigned int chroma_threshold;  /**< the chroma coefficients threshold (0 ~ 7) 
                                   */
  /// The luma coefficients threshold (0 ~ 7).
  unsigned int luma_threshold;    /**< the luma coefficients threshold (0 ~ 7) 
                                   */
  /// The beta offset for in-loop filter.
  unsigned int beta_offset;       /**< the beta offset for in-loop filter 
                                   */
  /// The alpha offset for in-loop filter.
  unsigned int alpha_offset;      /**< the alpha offset for in-loop filter 
                                   */
  /// The chroma qp offset (-12 to 12 inclusively).
  unsigned int chroma_qp_offset;  /**< the chroma qp offset (-12 to 12 inclusively) 
                                   */
  /// To disable in-loop filter or not.
  unsigned int disable_ilf;       /**< to disable in-loop filter or not
                                   */  
  /// To enable watermark function or not
  unsigned int watermark_enable;         /**< to enable watermark function or not 
                                          */
  /// The watermark interval.
  unsigned int watermark_interval;       /**< to specify the watermark interval if watermark function is enabled 
                                          */
  /// The initial watermark pattern.
  unsigned int watermark_init_pattern;   /**< to specify the initial watermark pattern if watermark function is enabled 
                                          */
  void          *bitstream;
  unsigned int  bitstream_size;
  int  		frame_cost;
  int           keyframe;
  /// The base address for input Y frame buffer.
  unsigned char *pu8YFrameBaseAddr;  /**< To set input Y frame buffer's base address.\n
                                      *   This variable can be used both in MPEG 2D mode and H.264 2D mode.
                                      *   <B>N.B.</B> : the input frame buffer address must be <B>physical address</B> with <B>8-byte aligned</B>.
                                      *   @see pu8UVFrameBaseAddr
                                      *   @see pu8UFrameBaseAddr
                                      *   @see pu8VFrameBaseAddr
                                      *   @see pu8BitstreamAddr
                                      *
                                      *   Also, this variable can be set by utilizing the function h264_encoder_setyuv_addr().
                                      *   @see h264_encoder_setyuv_addr
                                      */
  /// The base address for input UV frame buffer.	
  unsigned char *pu8UVFrameBaseAddr; /**< To set input UV frame buffer's base address.\n
                                      *   This variable is used only in H.264 2D mode.
                                      *   <B>N.B.</B> : the input frame buffer address must be <B>physical address</B> with <B>8-byte aligned</B>.
                                      *   @see pu8YFrameBaseAddr
                                      *   @see pu8VFrameBaseAddr
                                      *   @see pu8VFrameBaseAddr
                                      *   @see pu8BitstreamAddr
                                      *
                                      *   Also, this variable can be set by utilizing the function h264_encoder_setyuv_addr().
                                      *   @see h264_encoder_setyuv_addr
                                      */ 
  /// The base address for input U frame buffer.	
  unsigned char *pu8UFrameBaseAddr;  /**< To set input U frame buffer's base address.\n
                                      *   This variable is used only in MPEG 2D mode.
                                      *   <B>N.B.</B> : the input frame buffer address must be <B>physical address</B> with <B>8-byte aligned</B>.
                                      *   @see pu8YFrameBaseAddr
                                      *   @see pu8VFrameBaseAddr
                                      *   @see pu8BitstreamAddr
                                      *
                                      *   Also, this variable can be set by utilizing the function h264_encoder_setyuv_addr().
                                      *   @see h264_encoder_setyuv_addr
                                      */
  /// The base address for input V frame buffer.
  unsigned char *pu8VFrameBaseAddr;  /**< To set input V frame buffer's base address.\n
                                      *   This variable is used only in MPEG 2D mode.
                                      *   <B>N.B.</B> : the input frame buffer address must be <B>physical address</B> with <B>8-byte aligned</B>.
                                      *   @see pu8YFrameBaseAddr
                                      *   @see pu8UFrameBaseAddr
                                      *   @see pu8BitstreamAddr
                                      *
                                      *   Also, this variable can be set by utilizing the function h264_encoder_setyuv_addr().
                                      *   @see h264_encoder_setyuv_addr
                                      */
  /// The bitstream buffer address while encoding one single frame.
  unsigned char *pu8BitstreamAddr;  /**< To set output bitstream buffer's address.\n
                                     *  This bitstream buffer was provided by user and can be used to store
                                     *  the encoded bitstream while encoding one single frame.\n
                                     *   <B>N.B.</B> : the output bitstream buffer address must be <B>physical address</B> with <B>16-byte aligned</B>.
                                     *                 It was recommended that the size of bitstream buffer be the value
                                     *                 of (@ref u32FrameWidth * @ref u32FrameHeight * 3/2).
                                     *   @see pu8YFrameBaseAddr
                                     *   @see pu8UVFrameBaseAddr
                                     *   @see pu8UFrameBaseAddr
                                     *   @see pu8VFrameBaseAddr
                                     */
  /// The address of reconstruct frame buffer.
  unsigned char *pu8ReConstructFrame;/**< 
                                      *  To specify the reconstruct frame buffer address.\n
                                      *  The size of reconstruct frame buffer was equal to
                                      *  (@ref u32FrameWidth * @ref u32FrameHeight * 3/2).
                                      *  <B>N.B.</B> : the output reconstruct frame buffer 
                                      *                address must be <B>physical address</B> 
                                      *                with <B>16-byte aligned</B>.
                                      *
                                      *  @see pfnDmaMalloc
                                      *  @see pfnDmaFree
                                      */
  /// The address of reference frame buffer.
  unsigned char *pu8ReferenceFrame;  /**< 
                                      *  To specify the reference frame buffer address.\n
                                      *  The size of reference frame buffer was equal to
                                      *  (@ref u32FrameWidth * @ref u32FrameHeight * 3/2).
                                      *  <B>N.B.</B> : the reference frame buffer 
                                      *                address must be <B>physical address</B> 
                                      *                with <B>16-byte aligned</B>.
                                      *
                                      *  @see pfnDmaMalloc
                                      *  @see pfnDmaFree
                                      */
  /// The address of system info buffer.
  unsigned char *pu8SysInfoBuffer; /**< 
                                    *  To specify the address of system info buffer 
                                    *  The size of system info buffer was equal to
                                    *  ((MBs_Count_Width+1)/2) *64 *2).
                                    *  <B>N.B.</B> : the system info buffer 
                                    *                address must be <B>physical address</B> 
                                    *                with <B>4-byte aligned</B>.
                                    *
                                    *  @see pfnDmaMalloc
                                    *  @see pfnDmaFree
                                    */
  /// The virtual address of DMA buffer, which size is equal to ((4*19+2)*sizeof(unsigned int));
  unsigned char *pu8DMABuffer_virt; /**< 
                                     *  To specify the virtual address of DMA buffer.
                                     *  The size of DMA buffer was equal to
                                     *  ((4*19+2)*sizeof(unsigned int)).\n
                                     *  <B>N.B.</B> : this address must be <B>4-byte aligned</B>.
                                     *
                                     *  @see pfnDmaMalloc
                                     *  @see pfnDmaFree
                                     */
  /// The physical address of DMA buffer, which size is equal to ((4*19+2)*sizeof(unsigned int));
  unsigned char *pu8DMABuffer_phy;  /**< 
                                     *  To specify the physical address of DMA buffer.
                                     *  The size of DMA buffer was equal to
                                     *  ((4*19+2)*sizeof(unsigned int)).\n
                                     *  <B>N.B.</B> : this address must be <B>4-byte aligned</B>.
                                     *
                                     *  @see pfnDmaMalloc
                                     *  @see pfnDmaFree
                                     */

  /// The function pointer to user-defined DMA memory allocation function.
  FAVC_DMA_MALLOC_PTR pfnDmaMalloc; /**< This variable contains the function pointer to the user-defined 
                                *   DMA malloc function since under OS environment, our hardware device
                                *   may need the physical address instead of virtual address.
                                *
                                *   @see pfnDmaFree
                                *   @see DMA_MALLOC_PTR
                                *   @see DMA_FREE_PTR
                                */
  /// The function pointer to user-defined DMA free allocation function.
  FAVC_DMA_FREE_PTR   pfnDmaFree;   /**< This variable contains the function pointer to the user-defined 
                                *   DMA free function since under OS environment, our hardware device
                                *   may need the physical address instead of virtual address.
                                *
                                *   @see pfnDmaFree
                                *   @see DMA_MALLOC_PTR
                                *   @see DMA_FREE_PTR
                                */
    FAVC_MALLOC_PTR pfnMalloc;	
    FAVC_FREE_PTR pfnFree;
} FAVC_ENC_PARAM;


#ifdef SYSINFO_CIRCULER		
#define SYSBUF_SIZE(width, height) ( ((((width+15)/16)+1)/2)*64*2 )
#else
#define SYSBUF_SIZE(width, height) ( ((width+15)/16)*((height+15)/16)*64)
#endif 

// The Faraday H.264 Encoder SYSINFO Parameters Structure.
#define mv0_x_value(mb) (mb[8] & 0xFF)
#define mv0_y_value(mb) (mb[9] &0xFF )
#define mv1_x_value(mb) (mb[12] & 0xFF)
#define mv1_y_value(mb) (mb[13] &0xFF )
#define sad_lb_value(mb) ( ((mb[10] & 0xF0)>>4) |((mb[11] & 0x0F)<<4))
#define sad_hb_value(mb) ( ((mb[14] & 0xF0)>>4) |((mb[15] & 0x0F)<<4))

typedef struct {
    pid_t           pid;
    unsigned char   filename[30];
    unsigned int    enable;	
    unsigned int    interval;
	
    unsigned int    x0_LU;
    unsigned int    y0_LU;
    unsigned int    x0_RD;
    unsigned int    y0_RD;
    
    unsigned int    x1_LU;
    unsigned int    y1_LU;
    unsigned int    x1_RD;
    unsigned int    y1_RD;
    
    unsigned int    x2_LU;
    unsigned int    y2_LU;
    unsigned int    x2_RD;
    unsigned int    y2_RD;

    unsigned int    mv_th0;	
    unsigned int    sad_th0;
    unsigned int 	  alarm_idx0;
	
    unsigned int    mv_th1;	
    unsigned int    sad_th1;
    unsigned int 	  alarm_idx1;
	
    unsigned int    mv_th2;	
    unsigned int    sad_th2;
    unsigned int 	  alarm_idx2;
	
    // for output file index
    unsigned int    rotate;
    unsigned int    rotate_idx;
    unsigned int    frameindex;	
} FAVC_MD_INFO;

typedef struct {
    int    active0;        //the result of motion dection 
    int    active1;        //the result of motion dection 
    int    active2;        //the result of motion dection 
} FAVC_MD_RESULT;     

typedef struct {
	unsigned int enc_total;
	unsigned int enc_hw_total;
} FAVC_TOTAL_TIME;

#endif
